package handlers

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"gorm.io/gorm"
	"hello/database"
	"hello/models"
	"hello/utils"
	"net/http"
	"strconv"
	"strings"
)

func LoginUser(ctx *gin.Context) {
	var user models.User
	var LoginUserDTO models.LoginUserDTO
	// 绑定请求体到 updateUserDTO
	if err := ctx.ShouldBindJSON(&LoginUserDTO); err != nil {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "请求体格式错误: " + err.Error(),
			Data:    nil,
		})
		return
	}

	// 验证 updateUserDTO
	validate := validator.New()
	if err := validate.Struct(LoginUserDTO); err != nil {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "数据验证失败: " + err.Error(),
			Data:    nil,
		})
		return
	}

	// 根据名称和地址查找用户
	md5Hash := models.GenerateMD5(LoginUserDTO.Password)
	result := database.DB.Where("mobile = ? AND password = ?", LoginUserDTO.Mobile, md5Hash).First(&user)
	if err := result.Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusNotFound, utils.JSONResult{
				Code:    http.StatusNotFound,
				Message: "用户未找到",
				Data:    nil,
			})
		} else {
			ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
				Code:    http.StatusInternalServerError,
				Message: "查询用户时发生错误: " + err.Error(),
				Data:    nil,
			})
		}
		return
	}
	if user.Status != 1 {
		ctx.JSON(http.StatusForbidden, utils.JSONResult{
			Code:    http.StatusForbidden,
			Message: "用户已被禁用: ",
			Data:    nil,
		})
	}
	// 生成JWT
	userIDStr := strconv.FormatUint(uint64(user.ID), 10)
	token, err := utils.GenerateToken(userIDStr)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
			Code:    http.StatusInternalServerError,
			Message: "生成令牌时发生错误: " + err.Error(),
			Data:    nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, utils.JSONResult{
		Code:    http.StatusOK,
		Message: "创建成功",
		Data: map[string]interface{}{
			"token": token,
			"user":  user,
		},
	})
}

// CreateUser 创建用户
func CreateUser(ctx *gin.Context) {
	updateUserDTO := &models.UpdateUserDTO{}

	// 绑定请求体到 updateUserDTO
	if err := ctx.ShouldBindJSON(&updateUserDTO); err != nil {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "请求体格式错误",
			Data:    nil,
		})
		return
	}

	// 验证 updateUserDTO
	if err := updateUserDTO.Validate(); err != nil {
		errors := make(map[string]string)
		for _, err := range err.(validator.ValidationErrors) {
			errors[err.Field()] = err.Tag()
		}

		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "数据验证失败1",
			Data:    errors,
		})
		return
	}

	// 检查邮箱是否已被使用且状态为正常
	var emailUser models.User
	if err := database.DB.Where("email = ? and status = 1", updateUserDTO.Email).First(&emailUser).Error; err != nil {
		if err != gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusBadRequest, utils.JSONResult{
				Code:    http.StatusBadRequest,
				Message: "数据验证失败3",
				Data:    err.Error(),
			})
			return
		}
	} else {
		ctx.JSON(http.StatusConflict, utils.JSONResult{
			Code:    http.StatusConflict,
			Message: "该邮箱已被使用且状态正常",
			Data:    nil,
		})
		return
	}

	var mobileUser models.User
	if err := database.DB.Where("mobile = ? and status = 1", updateUserDTO.Mobile).First(&mobileUser).Error; err != nil {
		if err != gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusBadRequest, utils.JSONResult{
				Code:    http.StatusBadRequest,
				Message: "数据验证失败4",
				Data:    err.Error(),
			})
			return
		}
	} else {
		ctx.JSON(http.StatusConflict, utils.JSONResult{
			Code:    http.StatusConflict,
			Message: "该号码已被使用且状态正常",
			Data:    nil,
		})
		return
	}

	// 创建用户
	// 生成MD5哈希值
	md5Hash := models.GenerateMD5(updateUserDTO.Password)
	user := &models.User{
		Name:     updateUserDTO.Name,
		Address:  updateUserDTO.Address,
		Age:      updateUserDTO.Age,
		Status:   updateUserDTO.Status,
		Mobile:   updateUserDTO.Mobile,
		Email:    updateUserDTO.Email,
		Password: md5Hash,
	}
	//// 调用 Validate 方法验证用户数据
	//if err := user.Validate(); err != nil {
	//	errors := make(map[string]string)
	//	for _, err := range err.(validator.ValidationErrors) {
	//		errors[err.Field()] = err.Tag()
	//	}
	//
	//	ctx.JSON(http.StatusBadRequest, utils.JSONResult{
	//		Code:    http.StatusBadRequest,
	//		Message: "数据验证失败2",
	//		Data:    errors,
	//	})
	//	return
	//}
	result := database.DB.Create(user)

	// 处理数据库操作错误
	if err := result.Error; err != nil {
		// 检查是否为唯一约束错误
		if strings.Contains(err.Error(), "Duplicate entry") {
			ctx.JSON(http.StatusConflict, utils.JSONResult{
				Code:    http.StatusConflict,
				Message: "数据已存在",
				Data:    nil,
			})
			return
		}

		ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
			Code:    http.StatusInternalServerError,
			Message: "创建用户失败",
			Data:    nil,
		})
		return
	}

	// 返回成功结果
	ctx.JSON(http.StatusCreated, utils.JSONResult{
		Code:    http.StatusCreated,
		Message: "创建成功",
		Data:    user, // 返回完整的用户对象
	})
	return
}

// GetUser 获取用户信息
func GetUser(ctx *gin.Context) {
	var user models.User

	// 假设我们根据用户的ID来查询用户信息
	userID := ctx.Query("id")
	if userID == "" {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "id 参数是必需的",
			Data:    nil,
		})
		return
	}

	result := database.DB.First(&user, userID)
	err := result.Error
	if err != nil {
		// 判断错误类型，如果是记录未找到的错误，返回404状态码
		if err == gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusBadRequest, utils.JSONResult{
				Code:    http.StatusBadRequest,
				Message: "用户未找到",
				Data:    nil,
			})
		} else {
			// 返回500状态码以表示服务器错误
			ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
				Code:    http.StatusInternalServerError,
				Message: err.Error(),
				Data:    nil,
			})
		}
		return
	}

	ctx.JSON(http.StatusOK, utils.JSONResult{
		Code:    http.StatusOK,
		Message: "用户信息获取成功",
		Data:    user, // 返回具体的用户对象
	})
}

// UpdateUser 更新用户信息
func UpdateUser(ctx *gin.Context) {
	var user models.User
	var updateUserDTO models.UpdateUserDTO

	// 假设我们根据用户的ID来更新用户信息
	userID := ctx.Query("id")
	if userID == "" {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "id 参数是必需的",
			Data:    nil,
		})
		return
	}
	// 绑定请求体到 updateUserDTO
	if err := ctx.ShouldBindJSON(&updateUserDTO); err != nil {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "请求体格式错误: " + err.Error(),
			Data:    nil,
		})
		return
	}

	//验证updateUserDTO
	validate := validator.New()
	if err := validate.Struct(updateUserDTO); err != nil {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "数据验证失败: " + err.Error(),
			Data:    nil,
		})
		return
	}

	// 根据ID查询用户
	result := database.DB.First(&user, userID)
	if err := result.Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusNotFound, utils.JSONResult{
				Code:    http.StatusNotFound,
				Message: "用户未找到",
				Data:    nil,
			})
		} else {
			ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
				Code:    http.StatusInternalServerError,
				Message: "查询用户时发生错误: " + err.Error(),
				Data:    nil,
			})
		}
		return
	}

	// 更新用户信息
	user.Name = updateUserDTO.Name
	user.Address = updateUserDTO.Address
	user.Age = updateUserDTO.Age
	user.Status = updateUserDTO.Status
	user.Mobile = updateUserDTO.Mobile
	user.Email = updateUserDTO.Email
	user.Password = models.GenerateMD5(updateUserDTO.Password)
	result = database.DB.Save(&user)
	if err := result.Error; err != nil {
		ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
			Code:    http.StatusInternalServerError,
			Message: "更新用户时发生错误: " + err.Error(),
			Data:    nil,
		})
		return
	}
	// 返回成功的JSON结果
	ctx.JSON(http.StatusOK, utils.JSONResult{
		Code:    http.StatusOK,
		Message: "用户信息更新成功",
		Data:    user, // 返回更新后的用户对象
	})
}

// ListUser 获取用户列表
func ListUser(ctx *gin.Context) {
	var users []models.User

	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 查询总记录数
	var total int64
	database.DB.Model(&models.User{}).Count(&total)

	// 计算总页数
	totalPage := (total + int64(pageSize) - 1) / int64(pageSize)

	// 查询所有用户
	result := database.DB.Offset(offset).Limit(pageSize).Find(&users)
	if err := result.Error; err != nil {
		ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
			Code:    http.StatusInternalServerError,
			Message: "查询用户列表时发生错误: " + err.Error(),
			Data:    nil,
		})
		return
	}

	// 返回成功的JSON结果
	ctx.JSON(http.StatusOK, utils.JSONResult{
		Code:    http.StatusOK,
		Message: "用户列表获取成功",
		Data: utils.Pagination{
			Data:      users,
			TotalPage: totalPage,
			Total:     total,
			Page:      page,
			PageSize:  pageSize,
		},
	})
}

// DeleteUser 删除用户信息
func DeleteUser(ctx *gin.Context) {
	// 假设我们根据用户的ID来删除用户信息
	userID := ctx.Query("id")
	if userID == "" {
		ctx.JSON(http.StatusBadRequest, utils.JSONResult{
			Code:    http.StatusBadRequest,
			Message: "id 参数是必需的",
			Data:    nil,
		})
		return
	}

	// 根据ID查询用户，判断用户是否存在
	var user models.User
	result := database.DB.First(&user, userID)
	err := result.Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			ctx.JSON(http.StatusNotFound, utils.JSONResult{
				Code:    http.StatusNotFound,
				Message: "用户未找到",
				Data:    nil,
			})
		} else {
			ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
				Code:    http.StatusInternalServerError,
				Message: "查询用户时发生错误: " + err.Error(),
				Data:    nil,
			})
		}
		return
	}

	// 删除用户
	result = database.DB.Delete(&user)
	err = result.Error
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, utils.JSONResult{
			Code:    http.StatusInternalServerError,
			Message: "删除用户时发生错误: " + err.Error(),
			Data:    nil,
		})
		return
	}

	// 返回成功的JSON结果
	ctx.JSON(http.StatusOK, utils.JSONResult{
		Code:    http.StatusOK,
		Message: "用户信息删除成功",
		Data:    result.RowsAffected,
	})
}
